import pytest
from utils.get_driver import GetDriver
import base64

_screenshots = {}


def pytest_addoption(parser):
    """添加命令行参数"""
    parser.addoption(
        "--browser-type",
        action="store",
        default="chrome",
        help="浏览器类型: chrome, firefox, ie, edge, chrome_headless"
    )


def pytest_configure(config):
    """pytest配置钩子，用于并行测试时的特殊处理"""
    # 检查是否是并行测试
    if hasattr(config, 'workerinput'):
        # 这是一个worker进程
        worker_id = config.workerinput.get('workerid', 'master')
        # 只有当htmlpath存在时才进行替换
        if hasattr(config.option, 'htmlpath') and config.option.htmlpath:
            # 替换{worker_id}占位符
            if '{worker_id}' in config.option.htmlpath:
                config.option.htmlpath = config.option.htmlpath.replace('{worker_id}', worker_id)
            # 也处理gw{worker_id}格式
            elif 'gw{worker_id}' in config.option.htmlpath:
                config.option.htmlpath = config.option.htmlpath.replace('gw{worker_id}', f'gw{worker_id}')


@pytest.fixture(scope="session")
def browser_type(request):
    """获取浏览器类型参数"""
    return request.config.getoption("--browser-type")


@pytest.fixture(scope="session")
def driver(request, browser_type):
    """定义全局driver fixture，使用GetDriver管理类"""
    _driver = GetDriver.get_driver(browser_type)

    def fin():
        GetDriver.close()

    request.addfinalizer(fin)
    return _driver


@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
    """钩子函数，用于在测试失败时截图"""
    outcome = yield
    report = outcome.get_result()

    # 只在测试调用阶段且失败时处理
    if report.when == "call" and report.failed:
        # 获取driver fixture
        try:
            driver_fixture = item.funcargs.get('driver', None)
            if not driver_fixture and hasattr(item, '_request'):
                driver_fixture = item._request.getfixturevalue('driver')

            if driver_fixture:
                # 截图
                screenshot = driver_fixture.get_screenshot_as_png()
                # 编码为base64
                encoded_screenshot = base64.b64encode(screenshot).decode('utf-8')

                # 存储截图数据，使用测试节点ID作为键
                _screenshots[item.nodeid] = encoded_screenshot

        except Exception as e:
            # 如果截图失败，存储错误信息
            _screenshots[item.nodeid] = f"截图失败: {str(e)}"


def pytest_html_results_table_header(cells):
    """添加截图列到表格头部"""
    cells.insert(2, '<th class="sortable" data-column-type="Screenshot">Screenshot</th>')


def pytest_html_results_table_row(report, cells):
    """在表格行中添加截图列"""
    screenshot_cell = '<td class="col-screenshot"></td>'

    # 检查是否有截图数据
    if hasattr(report, 'nodeid') and report.nodeid in _screenshots:
        screenshot_data = _screenshots[report.nodeid]

        if screenshot_data.startswith("截图失败"):
            # 显示错误信息
            screenshot_cell = f'<td class="col-screenshot">{screenshot_data}</td>'
        else:
            # 显示截图缩略图
            screenshot_cell = f'''
            <td class="col-screenshot">
                <img src="data:image/png;base64,{screenshot_data}" 
                     alt="失败截图" 
                     style="width:100px;height:auto;cursor:pointer;border:1px solid #ddd;" 
                     onclick="
                        var modal = document.createElement('div');
                        modal.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.8);z-index:9999;display:flex;justify-content:center;align-items:center;';
                        modal.onclick = function() {{ document.body.removeChild(modal); }};
                        var img = document.createElement('img');
                        img.src = this.src;
                        img.style.cssText = 'max-width:90%;max-height:90%;border:2px solid white;';
                        modal.appendChild(img);
                        document.body.appendChild(modal);
                     " />
            </td>
            '''

    # 在Duration列之前插入截图列
    cells.insert(2, screenshot_cell)
